package com.kexio.common.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.kexio.common.constants.CommonConstants;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
 * 分页响应结果类
 * 
 * 用于封装分页查询的统一响应格式
 * 
 * @param <T> 数据类型
 * @author Kexio Team
 * @since 1.0.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PageResponse<T> implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    // ==================== 字段定义 ====================
    
    /** 数据列表 */
    private List<T> records;
    
    /** 总记录数 */
    private long total;
    
    /** 当前页码 */
    private long current;
    
    /** 每页大小 */
    private long size;
    
    /** 总页数 */
    private long pages;
    
    /** 是否有上一页 */
    private boolean hasPrevious;
    
    /** 是否有下一页 */
    private boolean hasNext;
    
    /** 是否是第一页 */
    private boolean isFirst;
    
    /** 是否是最后一页 */
    private boolean isLast;
    
    // ==================== 构造函数 ====================
    
    public PageResponse() {
        this.records = Collections.emptyList();
        this.total = 0;
        this.current = CommonConstants.DEFAULT_PAGE_NUM;
        this.size = CommonConstants.DEFAULT_PAGE_SIZE;
        calculatePages();
    }
    
    public PageResponse(List<T> records, long total, long current, long size) {
        this.records = records != null ? records : Collections.emptyList();
        this.total = Math.max(0, total);
        this.current = Math.max(1, current);
        this.size = Math.max(1, size);
        calculatePages();
    }
    
    // ==================== 静态工厂方法 ====================
    
    /**
     * 空分页结果
     */
    public static <T> PageResponse<T> empty() {
        return new PageResponse<>();
    }
    
    /**
     * 空分页结果（指定页码和大小）
     */
    public static <T> PageResponse<T> empty(long current, long size) {
        return new PageResponse<>(Collections.emptyList(), 0, current, size);
    }
    
    /**
     * 创建分页结果
     */
    public static <T> PageResponse<T> of(List<T> records, long total, long current, long size) {
        return new PageResponse<>(records, total, current, size);
    }
    
    
    // ==================== 私有方法 ====================
    
    /**
     * 计算页数和分页状态
     */
    private void calculatePages() {
        // 计算总页数
        if (this.size > 0) {
            this.pages = (this.total + this.size - 1) / this.size;
        } else {
            this.pages = 0;
        }
        
        // 确保当前页不超过总页数
        if (this.pages > 0 && this.current > this.pages) {
            this.current = this.pages;
        }
        
        // 计算分页状态
        this.hasPrevious = this.current > 1;
        this.hasNext = this.current < this.pages;
        this.isFirst = this.current == 1;
        this.isLast = this.current == this.pages || this.pages == 0;
    }
    
    // ==================== 便捷方法 ====================
    
    /**
     * 判断是否为空
     */
    public boolean isEmpty() {
        return this.records == null || this.records.isEmpty();
    }
    
    /**
     * 判断是否有数据
     */
    public boolean hasData() {
        return !isEmpty();
    }
    
    /**
     * 获取记录数量
     */
    public int getRecordCount() {
        return this.records != null ? this.records.size() : 0;
    }
    
    /**
     * 获取起始记录号（用于显示）
     */
    public long getStartRecord() {
        if (isEmpty()) {
            return 0;
        }
        return (this.current - 1) * this.size + 1;
    }
    
    /**
     * 获取结束记录号（用于显示）
     */
    public long getEndRecord() {
        if (isEmpty()) {
            return 0;
        }
        long end = this.current * this.size;
        return Math.min(end, this.total);
    }
    
    /**
     * 获取分页信息描述
     */
    public String getPageInfo() {
        if (isEmpty()) {
            return "暂无数据";
        }
        return String.format("第 %d-%d 条，共 %d 条", getStartRecord(), getEndRecord(), this.total);
    }
    
    /**
     * 获取数据列表（别名方法）
     */
    public List<T> getData() {
        return getRecords();
    }
    
    /**
     * 设置数据列表（别名方法）
     */
    public PageResponse<T> setData(List<T> data) {
        setRecords(data);
        return this;
    }
    
    // ==================== Getter 和 Setter ====================
    
    public List<T> getRecords() {
        return records;
    }
    
    public PageResponse<T> setRecords(List<T> records) {
        this.records = records != null ? records : Collections.emptyList();
        return this;
    }
    
    public long getTotal() {
        return total;
    }
    
    public PageResponse<T> setTotal(long total) {
        this.total = Math.max(0, total);
        calculatePages();
        return this;
    }
    
    public long getCurrent() {
        return current;
    }
    
    public PageResponse<T> setCurrent(long current) {
        this.current = Math.max(1, current);
        calculatePages();
        return this;
    }
    
    public long getSize() {
        return size;
    }
    
    public PageResponse<T> setSize(long size) {
        this.size = Math.max(1, size);
        calculatePages();
        return this;
    }
    
    public long getPages() {
        return pages;
    }
    
    public boolean isHasPrevious() {
        return hasPrevious;
    }
    
    public boolean isHasNext() {
        return hasNext;
    }
    
    public boolean isFirst() {
        return isFirst;
    }
    
    public boolean isLast() {
        return isLast;
    }
    
    // ==================== toString ====================
    
    @Override
    public String toString() {
        return "PageResponse{" +
               "total=" + total +
               ", current=" + current +
               ", size=" + size +
               ", pages=" + pages +
               ", recordCount=" + getRecordCount() +
               ", hasPrevious=" + hasPrevious +
               ", hasNext=" + hasNext +
               '}';
    }
}
